package com.benefm.multipar.pad.util;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DataUtil {

	public final static String defaultDatePattern = "yyyy-MM-dd HH:mm:ss";

//	public static void main(String[] args) throws Exception{
//		String hex="0000000000";
//		byte[] hexByte=new byte[12];
//		System.out.println(byteToHex(hexByte));
//	}

	public static String byteToHex(byte[] bytes) {
		String strHex = "";
		StringBuilder sb = new StringBuilder("");
		for (int n = 0; n < bytes.length; n++) {
			strHex = Integer.toHexString(bytes[n] & 0xFF);
			sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示，位数不够，高位补0
		}
		return sb.toString().trim();
	}

	private static byte hexToByte(String inHex){
		return (byte)Integer.parseInt(inHex,16);
	}

	public static byte[] hexToByteArray(String str) {
		int hexlen = str.length();
		byte[] result;
		if (hexlen % 2 == 1){
			//奇数
			hexlen++;
			result = new byte[(hexlen/2)];
			str="0"+str;
		}else {
			//偶数
			result = new byte[(hexlen/2)];
		}
		int j=0;
		for (int i = 0; i < hexlen; i+=2){
			result[j]=hexToByte(str.substring(i,i+2));
			j++;
		}
		return result;
	}


	public static void  Sort8S(byte[] arr, int n)
	{
		int i , j , k, t;

		if(arr.length >= n) {
			for (i = 0; i < n - 1; i++) {
				k = i;
				for (j = i + 1; j < n; j++) {
					if (arr[j] < arr[k]) {
						k = j;
					}
				}

				t = arr[k];
				arr[k] = arr[i];
				arr[i] = (byte) t;
			}
		}
	}

	public static Byte[] ByteArray(byte[] data) {
		if (data == null)
			return null;

		Byte[] outData = new Byte[data.length];
		for (int iLoop = 0; iLoop < data.length; iLoop++) {
			outData[iLoop] = new Byte(data[iLoop]);
		}

		return outData;
	}

	public final static byte[] Convert2byteArray(Byte[] data){
		byte[] xData = null;
		do {
			if(null == data){
				break;
			}
			if(0 >= data.length){
				break;
			}
			xData = new byte[data.length];
			for(int i = 0; i < data.length; i++){
				xData[i] = data[i];
			}
		}while (false);
		return xData;
	}

	/**
	 * 解析日期字符串
	 * @param strDateTime
	 * @param pattern
	 * @return
	 */
	public final static Date parseDateString(String strDateTime, String pattern) throws Exception {
		// 从字符串提取出日期
		String strPattern = pattern;
		if(strPattern.isEmpty())
		{
			strPattern = defaultDatePattern;
		}
		SimpleDateFormat format2 = new SimpleDateFormat(strPattern);
		Date date = null;
		try {
			//生成时间对象
			date = format2.parse(strDateTime);
		} catch (Exception e) {
			throw e;
		}
		return date;
	}

	public final static byte getBCD(byte value){
		return (byte) (((value / 10) << 4) + (value % 10));
	}



	final public static int getU16Value(byte[] data, int offset,
										boolean bigEndian) {
		int value = 0;
		do {
			if (null == data) {
				break;
			}
			if (0 > offset) {
				break;
			}
			if ((offset + 2) > data.length) {
				break;
			}
			if (bigEndian) {
				value = getU16Value(data[offset + 0], data[offset + 1]);
			} else {
				value = getU16Value(data[offset + 1], data[offset + 0]);
			}
		} while (false);

		return value;
	}

	public static int getU16Value(char[] data, int offset,
								  boolean bigEndian) {
		int value = 0;
		do {
			if (null == data) {
				break;
			}
			if (0 > offset) {
				break;
			}
			if ((offset + 2) > data.length) {
				break;
			}
			if (bigEndian) {
				value = getU16Value(data[offset + 0], data[offset + 1]);
			} else {
				value = getU16Value(data[offset + 1], data[offset + 0]);
			}
		} while (false);

		return value;
	}

	final public static int getU32Value(char[] data, int offset,
										boolean bigEndian) {
		int value = 0;
		do {
			if (null == data) {
				break;
			}
			if (0 > offset) {
				break;
			}
			if ((offset + 4) > data.length) {
				break;
			}
			if (bigEndian) {
				value = getU32Value(data[offset + 0], data[offset + 1],
						data[offset + 2], data[offset + 3]);
			} else {
				value = getU32Value(data[offset + 3], data[offset + 2],
						data[offset + 1], data[offset + 0]);
			}
		} while (false);

		return value;
	}


	final public static int getU32Value(byte[] data, int offset,
										boolean bigEndian) {
		int value = 0;
		do {
			if (null == data) {
				break;
			}
			if (0 > offset) {
				break;
			}
			if ((offset + 4) > data.length) {
				break;
			}
			if (bigEndian) {
				value = getU32Value(data[offset + 0], data[offset + 1],
						data[offset + 2], data[offset + 3]);
			} else {
				value = getU32Value(data[offset + 3], data[offset + 2],
						data[offset + 1], data[offset + 0]);
			}
		} while (false);

		return value;
	}

	/*
	 * Calendar转生日BCD YYMD
	 */
	public final static byte[] Calendar2BirthdayBCDDateTime(Calendar cal) {
		int i = 0;
		int value;
		byte[] dateTime = new byte[4];

		do {
			if (null == cal) {
				break;
			}
			value = cal.get(Calendar.YEAR);
			dateTime[i++] = getBCD((byte)(value/100));
			dateTime[i++] = getBCD((byte)(value%100));
			value = cal.get(Calendar.MONTH);
			dateTime[i++] = (byte) ((((value + 1) / 10) << 4) + ((value + 1) % 10));
			value = cal.get(Calendar.DAY_OF_MONTH);
			dateTime[i++] = (byte) (((value / 10) << 4) + (value % 10));
		} while (false);

		return dateTime;
	}

	public static byte[] ByteArray(Byte[] data) {
		if (data == null)
			return null;

		byte[] outData = new byte[data.length];
		for (int iLoop = 0; iLoop < data.length; iLoop++) {
			outData[iLoop] = data[iLoop].byteValue();
		}

		return outData;
	}

//	public final static boolean checkDateString(String strDate) {
//		boolean bRet = false;
//		do {
//			try {
//				if (StringHelper.StringIsEmptyOrNull(strDate)) {
//					break;
//				}
//				Date date = parseDate(strDate);
//				if (null == date) {
//					break;
//				}
//				bRet = true;
//			} catch (Exception e) {
//			}
//		} while (false);
//		return bRet;
//	}

	/**
	 * 获得默认�?date pattern
	 */
	public static String getDatePattern() {
		return defaultDatePattern;
	}


	/**
	 * 使用预设格式将字符串转为Date
	 */
//	public static Date parseDate(String strDate) throws ParseException {
//		Date date = null;
//		do {
//			if (!StringHelper.isText(strDate)) {
//				break;
//			}
//			date = parseDate(strDate, getDatePattern());
//		} while (false);
//		return date;
//	}

	/**
	 * 使用参数Format将字符串转为Date
	 */
//	public static Date parseDate(String strDate, String pattern)
//			throws ParseException {
//		Date date = null;
//
//		do {
//
//			if (!StringHelper.isText(strDate)) {
//				break;
//			}
//			if (!StringHelper.isText(pattern)) {
//				break;
//			}
//			date = new SimpleDateFormat(pattern).parse(strDate);
//		} while (false);
//
//		return date;
//	}

	final public static short getU8Value(char srcValue) {
		short value = 0;

		if (0 <= srcValue) {
			value = (short) srcValue;
		} else {
			value = (short) (srcValue + 256);
		}

		return value;
	}

	final public static short getU8Value(byte srcValue) {
		short value = 0;

		if (0 <= srcValue) {
			value = (short) srcValue;
		} else {
			value = (short) (srcValue + 256);
		}

		return value;
	}

	final public static int getU16Value(char hByteValue, char lByteValue) {
		int value = 0;

		value = getU8Value(hByteValue);
		value *= 256;
		value += getU8Value(lByteValue);

		return value;
	}

	final public static int getU16Value(byte hByteValue, byte lByteValue) {
		int value = 0;

		value = getU8Value(hByteValue);
		value *= 256;
		value += getU8Value(lByteValue);

		return value;
	}

	final public static int getU32Value(char hhByteValue, char hlByteValue,
										char lhByteValue, char llByteValue) {
		int value = 0;
		int tmpValue;

		tmpValue = getU8Value(hhByteValue);
		value = tmpValue << 24;
		tmpValue = getU8Value(hlByteValue);
		value += tmpValue << 16;
		tmpValue = getU8Value(lhByteValue);
		value += tmpValue << 8;
		tmpValue = getU8Value(llByteValue);
		value += tmpValue << 0;

		return value;
	}

	final public static int getU32Value(byte hhByteValue, byte hlByteValue,
										byte lhByteValue, byte llByteValue) {
		int value = 0;
		int tmpValue;

		tmpValue = getU8Value(hhByteValue);
		value = tmpValue << 24;
		tmpValue = getU8Value(hlByteValue);
		value += tmpValue << 16;
		tmpValue = getU8Value(lhByteValue);
		value += tmpValue << 8;
		tmpValue = getU8Value(llByteValue);
		value += tmpValue << 0;

		return value;
	}

	final public static int getU24Value( byte hlByteValue,
										 byte lhByteValue, byte llByteValue) {
		int value = 0;
		int tmpValue;

		byte hhByteValue = 0;
		if(0 > hlByteValue){
			hhByteValue = -1;
		}

		tmpValue = getU8Value(hhByteValue);
		value = tmpValue << 24;
		tmpValue = getU8Value(hlByteValue);
		value += tmpValue << 16;
		tmpValue = getU8Value(lhByteValue);
		value += tmpValue << 8;
		tmpValue = getU8Value(llByteValue);
		value += tmpValue << 0;

		return value;
	}


	final public static int getU24Value(byte[] data, int offset, boolean bigEndian) {
		int value = 0;
		do {
			if (null == data) {
				break;
			}
			if (0 > offset) {
				break;
			}
			if ((offset + 4) > data.length) {
				break;
			}
			if (bigEndian) {
				value = getU24Value(data[offset + 0], data[offset + 1],
						data[offset + 2]);
			} else {
				value = getU24Value(data[offset + 2],
						data[offset + 1], data[offset + 0]);
			}
		} while (false);

		return value;
	}


	/*
	 * short转byte数组
	 */
	final public static byte[] short2ByteArray(short value, boolean bigEndia) {
		int i = 0;
		byte[] data = new byte[2];

		if (bigEndia) {
			data[i++] = (byte) ((value >> 8) & 0xff);
			data[i++] = (byte) ((value >> 0) & 0xff);
		} else {
			data[i++] = (byte) ((value >> 0) & 0xff);
			data[i++] = (byte) ((value >> 8) & 0xff);
		}

		return data;
	}

	public static short byteArray2short(byte[] b, int index, boolean bigEndia) {
		short value;
		if (bigEndia) {
			value = (short) ((getU8Value(b[index + 0]) * 256) + (getU8Value(b[index + 1])));
		} else {
			value = (short) ((getU8Value(b[index + 1]) * 256) + (getU8Value(b[index + 0])));
		}
		return value;
	}

	public static short[] byteArray2ShortArray(byte[] xData, boolean bigEndia){
		int i,j;
		int num = xData.length/2;

		short[] xDestArr = new short[num];
		for(i = 0, j = 0; i < xData.length; i += 2){
			xDestArr[j++] = DataUtil.byteArray2short(xData, i, bigEndia);
		}
		return xDestArr;
	}

	/*
	 * int转byte数组
	 */
	final public static byte[] int2ByteArray(int value, boolean bigEndia) {
		int i = 0;
		byte[] data = new byte[4];

		if (bigEndia) {
			data[i++] = (byte) ((value >> 24) & 0xff);
			data[i++] = (byte) ((value >> 16) & 0xff);
			data[i++] = (byte) ((value >> 8) & 0xff);
			data[i++] = (byte) ((value >> 0) & 0xff);
		} else {
			data[i++] = (byte) ((value >> 0) & 0xff);
			data[i++] = (byte) ((value >> 8) & 0xff);
			data[i++] = (byte) ((value >> 16) & 0xff);
			data[i++] = (byte) ((value >> 24) & 0xff);
		}

		return data;
	}

	public static int byteArray2int(byte[] b, int index, boolean bigEndia) {
		int value;
		if (bigEndia) {
			value = (getU8Value(b[index + 0]) << 24) | (getU8Value(b[index + 1]) << 16)
					| (getU8Value(b[index + 1]) << 8) | (getU8Value(b[index + 3]) << 0);
		} else {
			value = (getU8Value(b[index + 3]) << 24) | (getU8Value(b[index + 2]) << 16)
					| (getU8Value(b[index + 1]) << 8) | (getU8Value(b[index + 0]) << 0);
		}
		return value;
	}

	public static int[] byteArray2IntArray(byte[] xData, boolean bigEndia){
		int i,j;
		int num = xData.length/4;

		int[] xDestArr = new int[num];
		for(i = 0, j = 0; i < xData.length; i += 4){
			xDestArr[j++] = DataUtil.byteArray2int(xData, i, bigEndia);
		}
		return xDestArr;
	}

	public static byte[] toLH(int n) {
		byte[] b = new byte[4];
		b[0] = (byte) (n & 0xff);
		b[1] = (byte) (n >> 8 & 0xff);
		b[2] = (byte) (n >> 16 & 0xff);
		b[3] = (byte) (n >> 24 & 0xff);
		return b;
	}

	public static byte[] toHH(int n) {
		byte[] b = new byte[4];
		b[3] = (byte) (n & 0xff);
		b[2] = (byte) (n >> 8 & 0xff);
		b[1] = (byte) (n >> 16 & 0xff);
		b[0] = (byte) (n >> 24 & 0xff);
		return b;
	}

	public int toLInt(byte[] b){
		int res = 0;
		for(int i=0;i<b.length;i++){
			res += (b[i] & 0xff) << (i*8);
		}
		return res;
	}

	public static int toHInt(byte[] b){
		int res = 0;
		for(int i=0;i<b.length;i++){
			res += (b[i] & 0xff) << ((3-i)*8);
		}
		return res;
	}

	public final static String pad(long c) {
		if (c >= 10)
			return String.valueOf(c);
		else
			return "0" + String.valueOf(c);
	}

	public final static String pad(int c) {
		if (c >= 10)
			return String.valueOf(c);
		else
			return "0" + String.valueOf(c);
	}

	public final static int BCD_DATE_TIME_YEAR = 0;
	public final static int BCD_DATE_TIME_MOUTH = 1;
	public final static int BCD_DATE_TIME_DAY = 2;
	public final static int BCD_DATE_TIME_HOUR = 3;
	public final static int BCD_DATE_TIME_MINUTE = 4;
	public final static int BCD_DATE_TIME_SECOND = 5;


	/*
	 * BCD时间转字符串
	 */
	public final static String bcdBirthday2SemicolonString(byte[] dateTime) {
		String str = "";

		do {
			if (null == dateTime) {
				break;
			}
			if(4 == dateTime.length) {
				str = pad(((dateTime[0] / 16) * 10 + dateTime[0] % 16) * 100 + (dateTime[1] / 16) * 10 + dateTime[1] % 16)
						+ "-"
						+ DataUtil.pad((dateTime[2] / 16) * 10 + dateTime[2] % 16)
						+ "-"
						+ DataUtil.pad((dateTime[3] / 16) * 10 + dateTime[3] % 16);
			}
			else{
				str = pad(2000 + (dateTime[0] / 16) * 10 + dateTime[0] % 16)
						+ "-"
						+ DataUtil.pad((dateTime[1] / 16) * 10 + dateTime[1] % 16)
						+ "-"
						+ DataUtil.pad((dateTime[2] / 16) * 10 + dateTime[2] % 16);
			}
		} while (false);

		return str;
	}

	/**
	 * 获得年龄
	 * @param birthday 年龄字符串 "yyyy-MM-dd"
	 * @return
	 * @throws ParseException
	 */
	public static final int getAge(String birthday) throws ParseException {
		int age = -1;
		do {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date currData = new Date();
//			String strBirthday = mPatientInfo.getStrBirthday()+" 00:00:00";
			Date dtOld = df.parse(birthday);
			age = currData.getYear()-dtOld.getYear();
			if(currData.getMonth() > dtOld.getMonth()){
				age++;
			}
			else if((currData.getMonth() == dtOld.getMonth())&&(currData.getDay() >= dtOld.getDay())){
				age++;
			}
		}while (false);
		return age;
	}

	/**
	 * 获得年龄
	 * @param birthday
	 * @return
	 * @throws ParseException
	 */
	public final static int getAgebyDate(Date birthday) throws ParseException {
		int age = -1;
		do {
			Date currData = new Date();
			age = currData.getYear()-birthday.getYear();
			if(currData.getMonth() > birthday.getMonth()){
				age++;
			}
			else if((currData.getMonth() == birthday.getMonth())&&(currData.getDay() >= birthday.getDay())){
				age++;
			}
		}while (false);
		return age;
	}

	public final static String bytes2String(byte[] xData){
		String str = "";

		try {
			int length = 0;
		    for (int i = 0; i < xData.length; i++) {
		        if (xData[i] == 0) {
					length = i;
					break;
				}
		    }
			if (length> 0) {
			    str = new String(xData, 0, length, "UTF-8");
			}
		}catch (Exception e){

		}

		return str;
	}

	/*
	 * BCD时间转字带分号符�?
	 */
	public final static String bcdDateTime2SemicolonString(byte[] dateTime) {
		String str = "";
		if(byteToHex(dateTime).startsWith("00000000")){
			return null;
		}
		do {
			if (null == dateTime) {
				break;
			}
			if(7 == dateTime.length) {
				str = pad((((dateTime[0] / 16) * 10 + dateTime[0] % 16)*100 + (dateTime[1] / 16) * 10 + dateTime[1] % 16))
						+ "-"
						+ DataUtil.pad((dateTime[2] / 16) * 10 + dateTime[2] % 16)
						+ "-"
						+ DataUtil.pad((dateTime[3] / 16) * 10 + dateTime[3] % 16)
						+ " "
						+ DataUtil.pad((dateTime[4] / 16) * 10 + dateTime[4] % 16)
						+ ":"
						+ DataUtil.pad((dateTime[5] / 16) * 10 + dateTime[5] % 16)
						+ ":"
						+ DataUtil.pad((dateTime[6] / 16) * 10 + dateTime[6] % 16);
			}
			else{
				str = pad((2000 + (dateTime[0] / 16) * 10 + dateTime[0] % 16))
						+ "-"
						+ DataUtil.pad((dateTime[1] / 16) * 10 + dateTime[1] % 16)
						+ "-"
						+ DataUtil.pad((dateTime[2] / 16) * 10 + dateTime[2] % 16)
						+ " "
						+ DataUtil.pad((dateTime[3] / 16) * 10 + dateTime[3] % 16)
						+ ":"
						+ DataUtil.pad((dateTime[4] / 16) * 10 + dateTime[4] % 16)
						+ ":"
						+ DataUtil.pad((dateTime[5] / 16) * 10 + dateTime[5] % 16);
			}
		} while (false);

		return str;
	}


	public static boolean isRunLinux(){
		boolean isLinux = System.getProperty("os.name").toLowerCase().indexOf("linux") >= 0;
		return isLinux;
	}

}
